package cn.edu.fudan.direct;

import cn.edu.fudan.data.HandelFeature;
import cn.edu.fudan.data.HandleDistance;
import cn.edu.fudan.data.SlideWindow;
import cn.edu.fudan.tools.GetConfig;
import cn.edu.fudan.type.Config;
import cn.edu.fudan.type.DataItem;
import cn.edu.fudan.type.Params;
import org.apache.log4j.Logger;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class TwoSideClassifiers {
	private Logger logger = Logger.getLogger(TwoSideClassifiers.class);
	
	private List<DataItem> feature_posi;
	private List<DataItem> feature_nega;
	private List<List<Long>> timepoints;

	public TwoSideClassifiers(List<DataItem> data_posi, List<DataItem> data_nega, List<List<Long>> timepoints) {
		super();
		this.feature_posi = data_posi;
		this.feature_nega = data_nega;
		this.timepoints = timepoints;
	}

	public double Classifier(Params params) {
		double accuracy = 0;
		Config config;
		try {
			config = new GetConfig().getConfig();
			HandelFeature handelFeature= new HandelFeature();
			SlideWindow slideWindow = new SlideWindow();
			HandleDistance handleDistance = new HandleDistance();
			
			List<List<List<DataItem>>> data_A = slideWindow.extractWindow(feature_posi,
					feature_nega, timepoints.get(0), config.getWindow_length());
			List<List<List<DataItem>>> data_B = slideWindow.extractWindow(feature_posi,
					feature_nega, timepoints.get(1), config.getWindow_length());
			
			List<List<Double>> maps_A = new ArrayList<>();
			List<List<Double>> maps_B = new ArrayList<>();

			for (int i = 0; i < data_A.size(); i++) {
				List<Double> map = new ArrayList<>();
				for (int j = 0; j < 2; j++) {
					map.addAll(handelFeature.handleFeature(data_A.get(i).get(j), config.getN_segment()));
				}
				maps_A.add(map);

			}

			for (int i = 0; i < data_B.size(); i++) {
				List<Double> map = new ArrayList<>();
				for (int j = 0; j < 2; j++) {
					map.addAll(handelFeature.handleFeature(data_B.get(i).get(j), config.getN_segment()));
				}
				maps_B.add(map);
			}		
			
			accuracy = handleDistance.calAccuracy(maps_A, maps_B, maps_A, maps_B, config.getK());
		
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return accuracy;

	}
}
